package com.diandi.signature.fddtools;

import com.alibaba.fastjson.JSON;
import com.diandi.signature.enums.platfrom.FddConstant;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;


/**
 * 法大大传输信息加密工具类
 * @author mwz
 * @create 2017-08-30 14:00
 * @version V1.0.0
 */

@Component
public class FddUtil {
	private static Logger logger = LoggerFactory.getLogger(FddUtil.class);
	private static Properties properties = new Properties();

	// 配置信息
	private static String API_ID;
	private static String APP_SECRET;
	private static String V;
	private static String API_URL;

	private static String charset = "UTF-8";

	/**
	 * 
	 * 系统加载
	 * 
	 * @author liuxu
	 * @since 2016年9月6日
	 */
	@PostConstruct
	private void initSys() {
		try {
			InputStream inputStream = FddUtil.class.getClassLoader().getResourceAsStream("fdd.properties");
			properties.load(inputStream);

			API_ID = properties.getProperty("API_ID");
			APP_SECRET = properties.getProperty("APP_SECRET");
			V = properties.getProperty("V");
			API_URL = properties.getProperty("API_URL");
		} catch (FileNotFoundException e) {
			logger.error("fdd.properties文件不存在!");
		} catch (IOException e) {
			logger.error("fdd.properties文件读取错误!");
		} catch (Exception e) {
			logger.error("fdd加载异常:{}", e.getMessage());
		}
	}

	/**
	 * <b>概要：</b> 个人注册免审核 <b>作者：</b>zhouxw </br> <b>日期：</b>2015年12月17日 </br>
	 * 
	 * @param customer_name
	 *            名称
	 * @param email
	 *            邮箱
	 * @param id_card
	 *            身份证号码
	 * @param mobile
	 *            手机号码
	 * @return 接口处理结果
	 */
	public static String invokeSyncPersonAuto(String customer_name, String id_card, String mobile) {
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));

			params.add(new BasicNameValuePair("app_id", API_ID));
			params.add(new BasicNameValuePair("timestamp", timeStamp));
			params.add(new BasicNameValuePair("v", V));
			params.add(new BasicNameValuePair("customer_name", customer_name));
			String id_mobile = FddEncryptTool.encrypt(id_card + "|" + mobile, APP_SECRET);
			params.add(new BasicNameValuePair("id_mobile", id_mobile));
			params.add(new BasicNameValuePair("msg_digest", msgDigest));
		} catch (Exception e) {
			logger.error("申请个人CA接口错误:customer_name:{},msg:{}", customer_name, e.getMessage());
		}
		return doPost(API_URL + FddConstant.URL_SYNCPERSON_AUTO.getValue(), params, charset);
	}

	/**
	 * <b>概要：</b> 自动签署 <b>作者：</b>zhouxw </br> <b>日期：</b>2015年12月30日 </br>
	 * 
	 * @param transaction_id
	 *            交易号
	 * @param customer_id
	 *            客户编号
	 * @param doc_url
	 *            文档URL，此参数已废弃，请传空字符串
	 * @param batch_id
	 *            批次号（交易号）
	 * @param client_type
	 *            客户类型：1-个人，2-企业
	 * @param client_role
	 *            客户角色
	 * @param contract_id
	 *            合同编号
	 * @param doc_title
	 *            文档标题
	 * @param sign_keyword
	 *            签章关键字
	 * @param notify_url
	 *            异步通知地址
	 * @param doc_type
	 *            文档类型，此参数已废弃，请传空字符串
	 * @return 接口处理结果
	 */
	public static String invokeExtSignAuto(String transaction_id, String customer_id, String batch_id,
			String client_type, String client_role, String contract_id, String doc_title, String sign_keyword,String notify_url ) {
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(transaction_id + timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET + customer_id));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));

			params.add(new BasicNameValuePair("app_id", API_ID));
			params.add(new BasicNameValuePair("timestamp", timeStamp));
			params.add(new BasicNameValuePair("v", V));
			params.add(new BasicNameValuePair("msg_digest", msgDigest));
			params.add(new BasicNameValuePair("transaction_id", transaction_id));
			params.add(new BasicNameValuePair("batch_id", batch_id));
			params.add(new BasicNameValuePair("contract_id", contract_id));
			params.add(new BasicNameValuePair("client_type", client_type));
			params.add(new BasicNameValuePair("client_role", client_role));
			params.add(new BasicNameValuePair("customer_id", customer_id));
			params.add(new BasicNameValuePair("doc_title", doc_title));
			params.add(new BasicNameValuePair("sign_keyword", sign_keyword));
			params.add(new BasicNameValuePair("notify_url", notify_url));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return doPost(API_URL + FddConstant.URL_EXTSIGN_AUTO.getValue(), params, charset);
	}

	/**
	 * <b>概要：</b> 合同归档 <b>作者：</b>zhouxw </br> <b>日期：</b>2015年12月18日 </br>
	 * 
	 * @param contract_id
	 *            合同编号
	 * @return 接口处理结果
	 */
	public static String invokeContractFilling(String contract_id) {
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET + contract_id));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));
			params.add(new BasicNameValuePair("app_id", API_ID));
			params.add(new BasicNameValuePair("timestamp", timeStamp));
			params.add(new BasicNameValuePair("v", V));
			params.add(new BasicNameValuePair("msg_digest", msgDigest));
			params.add(new BasicNameValuePair("contract_id", contract_id));
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("params:"+params.toString());
		return doPost(API_URL + FddConstant.URL_CONTRACTFILING.getValue(), params, charset);
	}

	/**
	 * <b>概要：</b> 修改用户信息 <b>作者：</b>zhouxw </br> <b>日期：</b>2015年12月23日 </br>
	 * 
	 * @param email
	 *            邮箱
	 * @param mobile
	 *            手机号码11位
	 * @param customer_id
	 *            客户编号
	 * @return 接口处理结果
	 */
	public static String invokeInfoChange(String mobile, String customer_id) {
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));
			params.add(new BasicNameValuePair("app_id", API_ID));
			params.add(new BasicNameValuePair("timestamp", timeStamp));
			params.add(new BasicNameValuePair("v", V));
			params.add(new BasicNameValuePair("msg_digest", msgDigest));
			params.add(new BasicNameValuePair("mobile", mobile));
			params.add(new BasicNameValuePair("customer_id", customer_id));

		} catch (Exception e) {
			e.printStackTrace();
		}

		return doPost(API_URL + FddConstant.URL_INFOCHANGE.getValue(), params, charset);
	}

	/**
	 * 
	 * 模板上传
	 * 
	 * @param templateId
	 * @param file
	 * @param docUrl
	 * @return String
	 * @author liuxu
	 * @since 2016年9月7日
	 */
	public static String invokeUploadTemplate(String templateId, File file, String docUrl) {
		String result = "";
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";

		/*	String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET + templateId));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));

			HttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(API_URL + FddConstant.URL_UPLOAD_TEMPLATE.getValue());
			FileBody fileBody = new FileBody(file);
			MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();

			reqEntity.addPart("app_id", new StringBody(API_ID, ContentType.DEFAULT_TEXT)); // 创建待处理的表单域内容文本
			reqEntity.addPart("v", new StringBody(V, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("timestamp", new StringBody(timeStamp, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("template_id", new StringBody(templateId, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("doc_url", new StringBody(docUrl, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("file", fileBody);
			reqEntity.addPart("msg_digest", new StringBody(msgDigest, ContentType.DEFAULT_TEXT));

			httpPost.setEntity(reqEntity.build());
			HttpResponse response = httpClient.execute(httpPost);
			if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
				HttpEntity entity = response.getEntity();
				// 显示内容
				if (entity != null) {
					result = EntityUtils.toString(entity);
				}
			}*/

		} catch (Exception e) {
			logger.error("上传模板接口错误:templateId:{},error:{}", templateId, e);
		}
		return result;
	}

	/**
	 * 
	 * 渲染生成模板
	 * 
	 * @param docTitle
	 * @param templateId
	 * @param contractId
	 * @param parameterMap
	 * @return String
	 * @author liuxu
	 * @since 2016年9月7日
	 */
	public static String invokeGenerateContract(String docTitle, String templateId, String contractId,
			Map<String, Object> parameterMap) {
		List<NameValuePair> params = new ArrayList<NameValuePair>();

		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String jsonParam = JSON.toJSONString(parameterMap);
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET + templateId + contractId) + jsonParam);
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));

			params.add(new BasicNameValuePair("app_id", API_ID));
			params.add(new BasicNameValuePair("v", V));
			params.add(new BasicNameValuePair("timestamp", timeStamp));
			params.add(new BasicNameValuePair("doc_title", docTitle));
			params.add(new BasicNameValuePair("template_id", templateId));
			params.add(new BasicNameValuePair("contract_id", contractId));
			params.add(new BasicNameValuePair("parameter_map", jsonParam));
			params.add(new BasicNameValuePair("msg_digest", msgDigest));
		} catch (Exception e) {
			logger.error("渲染模板接口错误:contractId:{},error:{}", contractId, e);
		}

		return doPost(API_URL + FddConstant.URL_GENERATE_CONTRACT.getValue(), params, charset);
	}

	/**
	 * 
	 * 文档上传
	 * 
	 * @param contractNo
	 * @param file
	 * @param docType
	 * @return String
	 * @author liuxu
	 * @since 2016年9月20日
	 */
	public static String invokeUploadDocs(String contractNo, File file, String docType) {
		String result = "";
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET + contractNo));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));

			HttpClient httpclient = new SSLClient();
			HttpPost httppost = new HttpPost(API_URL + FddConstant.URL_UPLOADDOCS.getValue());
			FileBody fileBody = new FileBody(file); // 创建待处理的文件
			MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
			reqEntity.addPart("file", fileBody);
			reqEntity.addPart("app_id", new StringBody(API_ID, ContentType.DEFAULT_TEXT)); // 创建待处理的表单域内容文本
			reqEntity.addPart("v", new StringBody(V, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("contract_id", new StringBody(contractNo, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("timestamp", new StringBody(timeStamp, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("msg_digest", new StringBody(msgDigest, ContentType.DEFAULT_TEXT));
			reqEntity.addPart("doc_type", new StringBody(docType, ContentType.DEFAULT_TEXT));
			httppost.setEntity(reqEntity.build());
			HttpResponse response = httpclient.execute(httppost);
			if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
				HttpEntity entity = response.getEntity();
				// 显示内容
				if (entity != null) {
					result = EntityUtils.toString(entity);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 
	 * 合同查看
	 * 
	 * @param contractNo
	 * @return String
	 * @author liuxu
	 * @since 2016年9月27日
	 */
	public static String invokeViewContract(String contractNo) {

		StringBuffer sb = new StringBuffer();
		try {
			String timeStamp = getTimeStamp();
			String msgDigest = "";
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timeStamp)
					+ FddEncryptTool.sha1(APP_SECRET + contractNo));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));

			sb.append(API_URL);
			sb.append(FddConstant.URL_VIEW_CONTRACT.getValue());
			sb.append("?");
			sb.append("app_id=" + API_ID);
			sb.append("&timestamp=" + timeStamp);
			sb.append("&v=" + V);
			sb.append("&msg_digest=" + msgDigest);
			sb.append("&contract_id=" + contractNo);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * 
	 * (这里用一句话描述这个方法的作用)
	 * 
	 * @return String
	 * @author liuxu
	 * @since 2016年9月6日
	 */
	public static String getTimeStamp() {
		Timestamp ts = new Timestamp(System.currentTimeMillis());
		DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.format(ts);
	}

	/**
	 * <b>概要：</b> post请求方法 <b>作者：</b>zhouxw </br> <b>日期：</b>2015年12月17日 </br>
	 * 
	 * @param url
	 * @param params
	 * @param charset
	 * @return 链接响应内容
	 */
	public static String doPost(String url, List<NameValuePair> params, String charset) {
		HttpClient httpClient = null;
		HttpPost httpPost = null;
		String result = null;
		try {
			httpClient = new SSLClient();
			httpPost = new HttpPost(url);
			// 设置参数
			if (null != params && params.size() > 0) {
				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, charset);
				httpPost.setEntity(entity);
			}
			HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					result = EntityUtils.toString(resEntity, charset);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}


	/**
	 * 得到msgDigest的值
	 * @param contractNo
	 * @return
	 */
	public static String invokeViewMsgDigest(String contractNo,String timestamp) {

		String msgDigest = "";
		try {
			String sha1 = FddEncryptTool.sha1(API_ID + FddEncryptTool.md5Digest(timestamp)
					+ FddEncryptTool.sha1(APP_SECRET + contractNo));
			msgDigest = new String(FddEncryptTool.Base64Encode(sha1.getBytes()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return msgDigest;
	}

	/*
	 * ===================================doPost==================================
	 * ============
	 */

}
